import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QGroupBox, QSizePolicy, QPushButton, QSpinBox
from PyQt6.QtCore import Qt, QTimer
from matplotlib.figure import Figure
import matplotlib.ticker as ticker
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import datetime


class TrendChart(FigureCanvas):
    def __init__(self, parent=None):
        fig = Figure(figsize=(5, 3), dpi=100)
        self.axes = fig.add_subplot(111)
        super(TrendChart, self).__init__(fig)

        self.setParent(parent)
        self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        self.updateGeometry()

        self.angle = 0  # 初始角度
        self.data = []  # 存储数据点
        self.x_min = datetime.datetime.now()  # 记录起始时间
        self.annotation = None  # 用于存储注释对象

        self.draw_trend_chart()

    def draw_trend_chart(self):
        # 清除之前的图形
        self.axes.clear()

        # 设置坐标轴范围
        x_max = datetime.datetime.now()
        if self.data:
            y_min = min([angle for _, angle in self.data]) - 1
            y_max = max([angle for _, angle in self.data]) + 1
        else:
            y_min = -1
            y_max = 1

        # 设置 X 轴和 Y 轴的标签
        self.axes.set_xlabel('Time')
        self.axes.set_ylabel('Angle()')

        # 设置 X 轴和 Y 轴的范围
        self.axes.set_xlim(self.x_min, x_max)
        self.axes.set_ylim(y_min, y_max)

        # 绘制 0 度的横线
        self.axes.axhline(y=0, color='r', linestyle='-', linewidth=1)

        # 设置 X 轴的刻度
        x_ticks = [self.x_min, x_max]
        x_tick_labels = [t.strftime('%H:%M:%S') for t in x_ticks]
        self.axes.set_xticks(x_ticks)
        self.axes.set_xticklabels(x_tick_labels)

        # 设置 Y 轴的刻度
        y_locator = ticker.MaxNLocator(nbins=8)  # 最多显示8个刻度
        self.axes.yaxis.set_major_locator(y_locator)

        # 显示网格
        self.axes.grid(True)

        # 调整子图的位置，使其整体上移
        self.figure.subplots_adjust(bottom=0.2)

        # 绘制数据点
        if self.data:
            times, angles = zip(*self.data)
            self.line, = self.axes.plot(times, angles, marker='o', linestyle='-', markersize=3)
            # self.connect_events(times, angles)

        # 更新图形
        self.draw()

    def connect_events(self, times, angles):
        self.annotation = self.axes.annotate("", xy=(0, 0), xytext=(20, 20),
                                             textcoords="offset points",
                                             bbox=dict(boxstyle="round", fc="w"),
                                             arrowprops=dict(arrowstyle="->"))
        self.annotation.set_visible(False)

        self.figure.canvas.mpl_connect("motion_notify_event", lambda event: self.on_hover(event, times, angles))
        self.figure.canvas.mpl_connect("figure_leave_event", self.on_leave)

    def on_hover(self, event, times, angles):
        if event.inaxes == self.axes:
            for i, (time, angle) in enumerate(zip(times, angles)):
                if self.line.contains(event)[0]:
                    if i == self.line.contains(event)[1]['ind'][0]:
                        self.annotation.xy = (time, angle)
                        self.annotation.set_text(f'Time: {time.strftime("%H:%M:%S")}\nAngle: {angle:.2f}')
                        self.annotation.set_visible(True)
                        self.draw_idle()
                        break
        else:
            self.annotation.set_visible(False)
            self.draw_idle()

    def on_leave(self, event):
        self.annotation.set_visible(False)
        self.draw_idle()

    def update_angle(self, angle):
        self.angle = angle
        current_time = datetime.datetime.now()
        self.data.append((current_time, self.angle))
        self.draw_trend_chart()

    def reset_x_min(self):
        self.x_min = datetime.datetime.now()
        self.draw_trend_chart()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.centralwidget = QWidget(self)
        self.setCentralWidget(self.centralwidget)

        self.groupBox = QGroupBox(parent=self.centralwidget)
        self.groupBox.setGeometry(290, 10, 411, 321)
        self.groupBox.setToolTipDuration(1)
        self.groupBox.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.groupBox.setFlat(False)
        self.groupBox.setObjectName("groupBox")

        layout = QVBoxLayout(self.groupBox)

        # 添加趋势图
        self.trend_chart = TrendChart(self.groupBox)
        layout.addWidget(self.trend_chart)

        # 添加角度输入控件
        self.angle_spinbox = QSpinBox(self.groupBox)
        self.angle_spinbox.setRange(-5, 365)
        self.angle_spinbox.setValue(0)
        layout.addWidget(self.angle_spinbox)

        # 添加开始按钮
        self.start_button = QPushButton("开始", self.groupBox)
        layout.addWidget(self.start_button)

        # 连接信号和槽
        self.start_button.clicked.connect(self.start_updates)
        self.angle_spinbox.valueChanged.connect(self.trend_chart.update_angle)

        self.setWindowTitle('Trend Chart Example')
        self.setGeometry(100, 100, 800, 600)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_chart)

    def start_updates(self):
        self.trend_chart.reset_x_min()  # 重置横坐标的起始点
        self.timer.start(200)  # 每2秒更新一次

    def update_chart(self):
        try:
            angle = self.angle_spinbox.value()
            self.trend_chart.update_angle(angle)
        except Exception as e:
            print(e)
            import traceback
            print(traceback.format_exc())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()

    sys.exit(app.exec())
